import pandas as pd
import numpy as np
from scipy.spatial.distance import euclidean
from sklearn.preprocessing import MinMaxScaler
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


# 数据加载函数（根据实际路径调整）
def get_data():
    def load_data():
        """加载所有需要的数据集"""
        data = {
            'teacher': pd.read_csv("data/1_teacher.csv"),
            'student': pd.read_csv("data/2_student_info.csv"),
            'chengji': pd.read_csv("data/5_chengji.csv"),
            'exam_type': pd.read_csv("data/6_exam_type.csv")
        }

        # 预处理：统一班级名称格式
        data['student']['cla_Name'] = data['student']['cla_Name'].str.replace(' ', '')
        data['teacher']['cla_Name'] = data['teacher']['cla_Name'].str.replace(' ', '')

        # 预处理：处理学生信息缺失值
        data['student']['bf_BornDate'] = pd.to_numeric(data['student']['bf_BornDate'], errors='coerce')
        data['student']['Bf_ResidenceType'] = data['student']['Bf_ResidenceType'].fillna('未知')

        return data


    # 全局参数配置
    CONFIG = {
        'current_cla': "白-高二(01)",
        'current_sub': "数学",
        'current_grade': "高二",
        'current_term': "2018-2019-1",
        'weights': {'similarity': 0.6, 'improvement': 0.4}
    }


    def get_class_profile(student_df, cla_name):
        """获取班级特征画像"""
        logging.info(f"正在生成班级 {cla_name} 的特征画像...")

        class_df = student_df[student_df['cla_Name'] == cla_name]
        if class_df.empty:
            logging.warning(f"未找到班级 {cla_name} 的学生数据")
            return None

        profile = {
            '学生人数': len(class_df),
            '性别比': class_df['bf_sex'].value_counts(normalize=True).get('男', 0),
            '城镇比例': class_df['Bf_ResidenceType'].value_counts(normalize=True).get('城镇', 0),
            '住校比例': class_df['bf_zhusu'].fillna(0).mean(),
            '共青团员': class_df['bf_policy'].str.contains('共青团员', na=False).mean(),
            '平均年龄': 2019 - class_df['bf_BornDate'].mean()
        }
        return profile


    def merge_score_data(chengji_df, student_df):
        """合并成绩数据与学生信息"""
        logging.info("正在合并成绩数据与学生信息...")

        merged_df = pd.merge(
            chengji_df,
            student_df[['bf_StudentID', 'cla_Name']],
            left_on='mes_StudentID',
            right_on='bf_StudentID',
            how='left'
        ).drop(columns=['bf_StudentID'])

        # 处理合并后的异常值
        merged_df['mes_Score'] = pd.to_numeric(merged_df['mes_Score'], errors='coerce')
        merged_df = merged_df[merged_df['mes_Score'] >= 0]  # 排除异常分数
        return merged_df


    def calculate_score_improvement(merged_df, subject_id, cla_name, term):
        """计算成绩提升度（修正版）"""
        logging.info(f"计算班级 {cla_name} 的成绩提升度...")

        exam_mapping = {
            '期中': [2, 20],
            '期末': [3, 21],
            '月考': [19, 22]
        }

        valid_exams = []
        for exam_type, type_ids in exam_mapping.items():
            exam_data = merged_df[
                (merged_df['exam_term'] == term) &
                (merged_df['mes_sub_id'] == subject_id) &
                (merged_df['cla_Name'] == cla_name) &
                (merged_df['exam_type'].isin(type_ids))
                ]

            if not exam_data.empty:
                z_score_mean = exam_data['mes_Z_Score'].mean()
                valid_exams.append((exam_type, z_score_mean))

        if len(valid_exams) >= 2:
            sorted_scores = sorted(valid_exams, key=lambda x: x[1])
            return sorted_scores[-1][1] - sorted_scores[0][1]
        return 0


    def calculate_similarity(current_profile, history_profile):
        """计算特征相似度（带归一化处理）"""
        features = ['性别比', '城镇比例', '住校比例', '共青团员']

        # 数据归一化
        scaler = MinMaxScaler()
        current_vec = scaler.fit_transform([list(current_profile[f] for f in features)])
        hist_vec = scaler.transform([list(history_profile[f] for f in features)])

        # 计算相似度
        similarity = 1 / (1 + euclidean(current_vec[0], hist_vec[0]))
        return similarity


    def main_analysis():
        """主分析流程"""
        data = load_data()

        # 获取当前班级画像
        current_profile = get_class_profile(data['student'], CONFIG['current_cla'])
        if not current_profile:
            raise ValueError("当前班级数据不存在")

        # 合并成绩数据
        merged_score = merge_score_data(data['chengji'], data['student'])

        # 获取候选教师
        candidate_teachers = data['teacher'][
            (data['teacher']['sub_Name'] == CONFIG['current_sub']) &
            (data['teacher']['gra_Name'] == CONFIG['current_grade'])
            ]['bas_id'].unique()

        results = []
        for teacher_id in candidate_teachers:
            teacher_info = data['teacher'][data['teacher']['bas_id'] == teacher_id].iloc[0]
            history_classes = data['teacher'][
                (data['teacher']['bas_id'] == teacher_id) &
                (data['teacher']['gra_Name'] == CONFIG['current_grade']) &
                (data['teacher']['sub_Name'] == CONFIG['current_sub'])
                ]

            total_similarity = 0
            total_improvement = 0
            valid_records = 0

            for _, hist_class in history_classes.iterrows():
                hist_profile = get_class_profile(data['student'], hist_class['cla_Name'])
                if not hist_profile:
                    continue

                improvement = calculate_score_improvement(
                    merged_score,
                    hist_class['sub_id'],
                    hist_class['cla_Name'],
                    hist_class['term']
                )

                similarity = calculate_similarity(current_profile, hist_profile)
                total_similarity += similarity
                total_improvement += improvement
                valid_records += 1

            if valid_records > 0:
                avg_similarity = total_similarity / valid_records
                avg_improvement = total_improvement / valid_records
                composite_score = (CONFIG['weights']['similarity'] * avg_similarity +
                                   CONFIG['weights']['improvement'] * avg_improvement)

                results.append({
                    '教师ID': teacher_id,
                    '教师姓名': teacher_info['bas_Name'],
                    '历史任教班级数': valid_records,
                    '平均相似度': round(avg_similarity, 4),
                    '平均提升度': round(avg_improvement, 4),
                    '综合评分': round(composite_score, 4)
                })

        # 生成结果
        result_df = pd.DataFrame(results).sort_values('综合评分', ascending=False)
        result_df.to_csv('teacher_evaluation_full.csv', index=False)
        logging.info("分析完成，结果已保存为 teacher_evaluation_full.csv")
        return result_df

#
# if __name__ == "__main__":
#     main_analysis()